﻿#include <iostream>
#include <fstream>
#include <meshing.hpp>

#include "core/statistics.hpp"
#include <chrono>

using namespace std;

namespace nglib{
    #include "nglib.h"
}


using namespace netgen;
using namespace nglib;


extern
void WriteVTK(const Mesh* Msh,const string path);


/*
提取Geo文件的模型文件位置和网格参数
*/

#include <map>
#include <string>
#include <sstream>
#include <regex>

/*
读取x.geo文件从中获取到 几何模型的路径和网格约束参数
*/

map<string,string>
makeMap(const string& filename){
    map<string,string> paras;

    ifstream geoFile(filename.c_str());
    string line;
    //正则匹配    
    while(getline(geoFile,line)){

        //Merge： 匹配集合文件路径
        if(regex_search(line,regex("\\bMerge"))){
            // cout<<line<<endl;
            smatch v;
            regex_search(line,v,regex("\"(.*)\""));
            // cout<< v.str(1)<<endl;     
            paras.insert(make_pair<string,string>("brep",v.str(1)));
        }

        if(regex_search(line,regex("CharacteristicLengthMin|CharacteristicLengthMax"))){

          //转换格式 Min= %SizeMin%;Max= %SizeMax%; 
          line =  regex_replace(line,regex("Mesh\\.CharacteristicLength(\\w+)\\b"),"$1");
        
          smatch v;
          regex_search(line,v,regex("(\\w+)\\s*=\\s*(\\d+)"));

         // cout<<v.str(1)<<v.str(2)<<endl;  

            paras.insert(make_pair<string,string>(v.str(1),v.str(2)));
        }
        //cout<<line<<endl;
    }

    return paras;
}
/*
"E:/haoyu/fastcae-build/FastCAE/Code/main/../../output/bin_d/../temp/gmsh.Geo"
"E:/haoyu/fastcae-build/FastCAE/Code/main/../../output/bin_d/gmsh/gmsh E:/haoyu/fastcae-build/FastCAE/Code/main/../../output/bin_d/../temp/gmsh.Geo -format vtk -bin 
-o E:/haoyu/fastcae-build/FastCAE/Code/main/../../output/bin_d/../temp/mesh.vtk -3"
*/


int main(int argc,char *argv[]){

    if(argc < 2){
        return EXIT_FAILURE;
    }
    //附上合适的数值
    string geofile = argv[1];
    string vtkfile;
    for(int i=1;i<=argc;i++){
        if(0 == strcmp("-o",argv[i])){
            vtkfile = argv[i+1];
            break;
        }
    }

    map<string,string> paras = makeMap(geofile);

    for(auto &para :paras){
        cout<<para.first<<para.second<<endl;
    }

    map<string,string>::iterator iter = paras.find("brep");
    if(iter == paras.end()){
        //没有模型文件
        return EXIT_FAILURE;
    }
    string brep(iter->second);

#if 1
    Ng_Init();

    Ng_Mesh *msh= Ng_NewMesh();
    Ng_Meshing_Parameters mp;

    double min = mp.minh;
    double max = mp.maxh;

    //设置参数
    map<string,string>::iterator i = paras.find("Min");
    if( i != paras.end()){
        cout<<"Min==="<<i->second<<endl;
        min = stof(i->second);
    }

    /*map<string,string>::iterator*/ i = paras.find("Max");
    if( i != paras.end()){
        max = stof(i->second);
        
    }

    cout<<"min"<<min<<"max"<<max<<endl;

    mp.minh = min;
    mp.maxh =max;  

    mp.fineness = 0.7;
    mp.grading = 0;

    Ng_OCC_Geometry *geom = Ng_OCC_Load_BREP(brep.c_str()); 

    Ng_OCC_SetLocalMeshSize(geom,msh,&mp);

    Ng_OCC_GenerateEdgeMesh(geom,msh,&mp);

    Ng_OCC_GenerateSurfaceMesh(geom,msh,&mp);    

    Ng_GenerateVolumeMesh(msh,&mp);
    //输出vtk格式

    Ng_OCC_Uniform_Refinement(geom,msh);

    Mesh *Msh = reinterpret_cast<Mesh*>(msh);

    // string path ("./sample.vtk");

    WriteVTK(Msh,vtkfile);

    cout<<"end"<<endl;    
    ngcore::Statistics::print();

    Ng_Exit();       

#endif

    return EXIT_SUCCESS;
}